import 'dart:io';
import 'dart:typed_data';
import 'package:image/image.dart' as img;
import 'package:video_compress/video_compress.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'logger.dart';

/// 压缩工具类
/// 用于压缩图片和视频，减少上传文件大小
/// 
/// 使用纯Dart实现的image包进行图片压缩，无需native assets
class CompressUtils {
  /// 压缩图片
  /// 
  /// @param imageFile 原始图片文件
  /// @param quality 压缩质量 (0-100，推荐85)
  /// @param maxWidth 最大宽度（像素），null表示不限制
  /// @param maxHeight 最大高度（像素），null表示不限制
  /// @return 压缩后的图片文件
  static Future<File?> compressImage(
    File imageFile, {
    int quality = 85,
    int? maxWidth,
    int? maxHeight,
  }) async {
    try {
      Logger.d('COMPRESS', '开始压缩图片: ${imageFile.path}');
      
      // 获取原始文件大小
      final originalSize = await imageFile.length();
      Logger.d('COMPRESS', '原始图片大小: ${(originalSize / 1024 / 1024).toStringAsFixed(2)}MB');
      
      // 如果文件小于500KB，不压缩
      if (originalSize < 500 * 1024) {
        Logger.d('COMPRESS', '图片文件较小，跳过压缩');
        return imageFile;
      }
      
      // 读取图片
      final bytes = await imageFile.readAsBytes();
      img.Image? image = img.decodeImage(bytes);
      
      if (image == null) {
        Logger.w('COMPRESS', '无法解码图片，返回原文件');
        return imageFile;
      }
      
      // 计算缩放后的尺寸
      int targetWidth = image.width;
      int targetHeight = image.height;
      
      if (maxWidth != null && image.width > maxWidth) {
        targetWidth = maxWidth;
        targetHeight = (image.height * maxWidth / image.width).round();
      }
      
      if (maxHeight != null && targetHeight > maxHeight) {
        targetHeight = maxHeight;
        targetWidth = (targetWidth * maxHeight / targetHeight).round();
      }
      
      // 如果需要缩放
      if (targetWidth != image.width || targetHeight != image.height) {
        Logger.d('COMPRESS', '缩放图片: ${image.width}x${image.height} -> ${targetWidth}x$targetHeight');
        image = img.copyResize(image, width: targetWidth, height: targetHeight);
      }
      
      // 获取临时目录
      final tempDir = await getTemporaryDirectory();
      final targetPath = path.join(
        tempDir.path,
        'compressed_${DateTime.now().millisecondsSinceEpoch}.jpg',
      );
      
      // 压缩并保存为JPEG
      final compressedBytes = img.encodeJpg(image, quality: quality);
      final compressedFile = File(targetPath);
      await compressedFile.writeAsBytes(compressedBytes);
      
      // 获取压缩后文件大小
      final compressedSize = compressedBytes.length;
      final compressionRatio = ((1 - compressedSize / originalSize) * 100).toStringAsFixed(1);
      
      Logger.d('COMPRESS', '压缩后图片大小: ${(compressedSize / 1024 / 1024).toStringAsFixed(2)}MB');
      Logger.d('COMPRESS', '压缩率: ${compressionRatio}%');
      
      // 如果压缩后反而更大，返回原文件
      if (compressedSize >= originalSize) {
        Logger.d('COMPRESS', '压缩后文件更大，返回原文件');
        await compressedFile.delete();
        return imageFile;
      }
      
      return compressedFile;
    } catch (e) {
      Logger.e('COMPRESS', '图片压缩异常: $e');
      // 压缩失败时返回原文件
      return imageFile;
    }
  }

  /// 压缩视频
  /// 
  /// @param videoFile 原始视频文件
  /// @param quality 压缩质量 (VideoQuality枚举)
  /// @return 压缩后的视频文件
  static Future<File?> compressVideo(
    File videoFile, {
    VideoQuality quality = VideoQuality.MediumQuality,
  }) async {
    try {
      Logger.d('COMPRESS', '开始压缩视频: ${videoFile.path}');
      
      // 获取原始文件大小
      final originalSize = await videoFile.length();
      Logger.d('COMPRESS', '原始视频大小: ${(originalSize / 1024 / 1024).toStringAsFixed(2)}MB');
      
      // 如果文件小于10MB，不压缩
      if (originalSize < 10 * 1024 * 1024) {
        Logger.d('COMPRESS', '视频文件较小，跳过压缩');
        return videoFile;
      }
      
      // 压缩视频
      final mediaInfo = await VideoCompress.compressVideo(
        videoFile.path,
        quality: quality,
        deleteOrigin: false, // 保留原文件
        includeAudio: true, // 包含音频
        frameRate: 30, // 帧率
      );
      
      if (mediaInfo == null || mediaInfo.path == null) {
        Logger.w('COMPRESS', '视频压缩失败，返回原文件');
        return videoFile;
      }
      
      final compressedFile = File(mediaInfo.path!);
      
      // 获取压缩后文件大小
      final compressedSize = await compressedFile.length();
      final compressionRatio = ((1 - compressedSize / originalSize) * 100).toStringAsFixed(1);
      
      Logger.d('COMPRESS', '压缩后视频大小: ${(compressedSize / 1024 / 1024).toStringAsFixed(2)}MB');
      Logger.d('COMPRESS', '压缩率: ${compressionRatio}%');
      
      return compressedFile;
    } catch (e) {
      Logger.e('COMPRESS', '视频压缩异常: $e');
      // 压缩失败时返回原文件
      return videoFile;
    }
  }

  /// 压缩封面图片（用于文章、视频封面等）
  /// 使用较小的尺寸和质量，进一步减小文件大小
  static Future<File?> compressCoverImage(File imageFile) async {
    return compressImage(
      imageFile,
      quality: 80, // 封面图片质量可以稍低
      maxWidth: 1920, // 最大宽度1920px
      maxHeight: 1080, // 最大高度1080px
    );
  }

  /// 压缩内容图片（用于图文动态等）
  /// 保持较高质量，但限制尺寸
  static Future<File?> compressContentImage(File imageFile) async {
    return compressImage(
      imageFile,
      quality: 85, // 内容图片质量稍高
      maxWidth: 2048, // 最大宽度2048px
      maxHeight: 2048, // 最大高度2048px
    );
  }
}
